package com.koron.operation.startlog.services.imp;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt;
import com.google.common.collect.Lists;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.operation.dispatch.service.imp.EquipmentRunServiceDeImp;
import com.koron.operation.startlog.bean.EqUnitDanageNameBo;
import com.koron.operation.startlog.bean.StartLogBean;
import com.koron.operation.startlog.bean.StartLogChangeBean;
import com.koron.operation.startlog.bean.dto.StartLogDto;
import com.koron.operation.startlog.bean.dto.StartOperDto;
import com.koron.operation.startlog.mapper.StartLogBeanMapper;
import com.koron.operation.startlog.mapper.StartLogChangeBeanMapper;
import com.koron.operation.startlog.services.StartLogService;
import com.koron.operation.util.StarLogUntil;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StartLogServiceImp implements StartLogService {

    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    private final static long interval = 30;//同步记录间隔时间（分钟）  大于此分钟才会记录

    /**
     * 提交开停机操作
     *
     * @param bean
     */
    @Override
    @TaskAnnotation("saveStartLog")
    public void saveStartLog(SessionFactory factory, StartLogBean bean) {
        StartLogBeanMapper mapper = factory.getMapper(StartLogBeanMapper.class);
        EquipmentRunServiceDeImp.BaseEqPackage(bean, factory);
        bean.setOperateUser(getCurrUser().getAccount());
        bean.setOperateUserMan(getCurrUser().getName());
        bean.setId(CodeTools.getCode32());
        mapper.insertSelective(bean);
        return;


    }

    @Override
    @TaskAnnotation("queryList")
    public List<StartOperDto> queryList(SessionFactory factory) {
        List<StartOperDto> list = factory.getMapper(StartLogBeanMapper.class).queryList();
        return list;
    }

    /**
     *
     * 注意 厂站级管理单位 必须是部门
     * @param factory
     * @return
     */
    @Override
    @TaskAnnotation("cockpitVoqueryList")
    public List<StartOperDto> cockpitVoqueryList(SessionFactory factory) {
        StartLogBeanMapper mapper = factory.getMapper(StartLogBeanMapper.class);
        List<StartOperDto> list = mapper.queryList();//机组设备最新开关机状态
        List<EqUnitDanageNameBo> relationship = mapper.getRelationship();//
        // 管理单位id-台账id
        Map<String, String> denageIdEqIdmap = Opt.ofNullable(relationship.stream().collect(Collectors.toMap(EqUnitDanageNameBo::getParamResult, EqUnitDanageNameBo::getId, (m1, m2) -> m1))).orElse(new HashMap<>());
        if (CollUtil.isNotEmpty(list)) {
            list.stream().forEach(s->{
                s.setDeptManageEquipmentId(denageIdEqIdmap.get(s.getDeptManage()));
            });
        }
        return list;
    }

    /**
     * 开停机日志列表(分页)
     *
     * @param dto
     * @return
     */
    @Override
    @TaskAnnotation("querylogList")
    public List<StartLogBean> querylogList(SessionFactory factory, StartLogDto dto) {
        StartLogBeanMapper mapper = factory.getMapper(StartLogBeanMapper.class);
        List<StartLogBean> list = mapper.queryAll(dto);
        return list;

    }

    /**
     * 开停机日志详情
     *
     * @param id
     * @return
     */
    @Override
    @TaskAnnotation("logDetails")
    public StartLogBean logDetails(SessionFactory factory, String id) {
        StartLogBeanMapper startLogBeanMapper = factory.getMapper(StartLogBeanMapper.class);
        StartLogBean bean = startLogBeanMapper.selectByPrimaryKey(id);
        StartLogBean topbean = startLogBeanMapper.queryFirstByEquipmentIdFQ(bean.getEquipmentId());
        if (bean.getId().equals(topbean.getId())) {
            bean.setIsTopOne(true);
        } else {
            bean.setIsTopOne(false);
        }

        StartLogChangeBeanMapper mapper = factory.getMapper(StartLogChangeBeanMapper.class);
        List<StartLogChangeBean> changeDet = mapper.queryAllBySourceId(id);
        bean.setChangeDet(changeDet);
        return bean;

    }


    @Override
    @TaskAnnotation("update")
    public String update(SessionFactory factory, StartLogBean bean) {
        factory.getMapper(StartLogBeanMapper.class).updateByPrimaryKeySelective(bean);
        return bean.getId();
    }

    @Override
    @TaskAnnotation("bathInsert")
    public void bathInsert(SessionFactory factory, List<StartLogBean> list) {

        Map<String, List<StartLogBean>> unitlistmap = list.stream().collect(Collectors.groupingBy(StartLogBean::getEquipmentId));//对抓取数据 用设备id 进行分组

        List<StartLogBean> filterlist = new ArrayList();

        /**
         * 如果相邻记录相隔时间 不到 30 分钟，视为不合理数据过滤掉
         */
        for (String s : unitlistmap.keySet()) {
            List<StartLogBean> unitlist = unitlistmap.get(s);
            Date compareTime = new Date();  //上一个入库记录的操作时间
            String beforType = "";          //上一个入库记录的操作类型
            for (int i = 0; i < unitlist.size(); i++) {
                String operateType = unitlist.get(i).getOperateType();
                unitlist.get(i).setInPlan(StarLogUntil.inplanConfig(operateType));  //根据类型 判定计划内外

                if (i == 0) {
                    compareTime = unitlist.get(i).getOperateTime();
                    beforType = unitlist.get(i).getOperateType();
                    unitlist.get(i).setIsErr(false);
                    filterlist.add(unitlist.get(i));
                    continue;
                }
                long between = DateUtil.between(compareTime, unitlist.get(i).getOperateTime(), DateUnit.MINUTE);//与上一记录操作时间比较

                if (between > interval) {
                    compareTime = unitlist.get(i).getOperateTime();
                    String nowType = unitlist.get(i).getOperateType();
                    unitlist.get(i).setIsErr(StarLogUntil.checkIsErr(nowType, beforType));
                    beforType = unitlist.get(i).getOperateType();
                    filterlist.add(unitlist.get(i));
                }
            }
        }
        List<List<StartLogBean>> partition = Lists.partition(filterlist, 300);

        partition.stream().forEach(p -> {
            factory.getMapper(StartLogBeanMapper.class).batchInsert(p);
        });
        return;
    }
}
